/////////////////////////////////////////////////////////////////////////////////
//      OpenDNS Updater
//      Copyright (C) 2008 Jason Strese
//
//      This program is free software: you can redistribute it and/or modify
//      it under the terms of the GNU General Public License as published by
//      the Free Software Foundation, either version 3 of the License, or
//      (at your option) any later version.
//
//      This program is distributed in the hope that it will be useful,
//      but WITHOUT ANY WARRANTY; without even the implied warranty of
//      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//      GNU General Public License for more details.
//
//      You should have received a copy of the GNU General Public License
//      along with this program.  If not, see <http://www.gnu.org/licenses/>.
/////////////////////////////////////////////////////////////////////////////////

using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;

namespace OpenDNSUpdater
{
    class Downloader
    {
        //
        // Constructor
        //
        public Downloader(Uri URI, string FileName, System.Net.NetworkCredential Credentials)
        {
            this._URI = URI;
            this._FileName = FileName;
            this._Credentials = Credentials;
        }

        #region Variables & Declarations

        //
        // Location
        //
        private Uri _URI = null;
        private string _FileName = string.Empty;
        private System.Net.NetworkCredential _Credentials = null;

        //
        // Internal Buffering
        //
        public bool _useInteralBuffering = false;
        public string _internalBuffer = string.Empty;

        //
        // Status
        //
        private bool _Busy = false;
        private long _TotalBytes = 0;
        private int _Downloaded = 0;

        #endregion

        #region Properties

        //
        // FileName
        //
        [Description("Get or set the filename of the downloading file (the file will be saved as this) - must include file extension.")]
        public string FileName
        {
            get { return this._FileName; }
            set { this._FileName = value; }
        }
        
        //
        // DownloadUri
        //
        [Description("Get or set the download Uri (path to the downloadable file).")]
        public Uri DownloadUri
        {
            get { return this._URI; }
            set { this._URI = value; }
        }

        //
        // Credentials
        //
        [Description("Get or set the network credentials.")]
        public System.Net.NetworkCredential Credentials
        {
            get { return this._Credentials; }
            set { this._Credentials = value; }
        }

        //
        // Busy
        //
        [Description("The state of the download progress (true if still downloading, else false).")]
        public bool Busy
        {
            get { return this._Busy; }
        }

        //
        // TotalBytes
        //
        [Description("Get the total amount of bytes that must be downloaded.")]
        public long TotalBytes
        {
            get { return this._TotalBytes; }
        }

        //
        // DownloadedBytes
        //
        [Description("Get the amount of bytes that are already downloaded.")]
        public int DownloadedBytes
        {
            get { return this._Downloaded; }
        }

        #endregion

        #region Public Functions

        //
        // InitiateDownload_InternalBuffering
        //
        [STAThread()]
        [Description("Start downloading the file. Uses internal buffering instead of files.")]
        public void __InitiateDownload_InternalBuffering()
        {
            ////////////////////////
            // A few declarations //
            ////////////////////////
            byte[] buffer = new byte[1024];
            System.IO.Stream iPart = null;
            System.Net.HttpWebResponse iURL = null;

            //
            // Set the status busy to true
            //
            this._Busy = true;

            //
            // Request the downloadable file
            //
            System.Net.HttpWebRequest iReq = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(this._URI);

            //
            // If there are credentials to supply, send them
            //
            if (this._Credentials != null)
            {
                iReq.Credentials = this._Credentials;
            }

            //
            // 401 (Bad Auth) Protection
            //
            try
            {
                //
                // Get the stream for the file we are about to download
                //
                iPart = iReq.GetResponse().GetResponseStream();

                //
                // Used to get the content length
                //
                iURL = (System.Net.HttpWebResponse)iReq.GetResponse();

                //
                // Set Total Bytes
                //
                this._TotalBytes = iURL.ContentLength;
            }
            catch (System.Net.WebException)
            {
                System.Windows.Forms.MessageBox.Show("You entered an invalid username or password.\r\nThe server rejected you.", "Error", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Exclamation, System.Windows.Forms.MessageBoxDefaultButton.Button1);
                iPart = System.IO.Stream.Null;
            }

            //
            // Read the stream
            //
            using(System.IO.StreamReader iReader = new System.IO.StreamReader(iPart))
            {
                this._internalBuffer = iReader.ReadToEnd();
            }

            //
            // We are no longer busy, set busy to false
            //
            this._Busy = false;

            //
            // Close remaining stream readers and file connections
            //
            iPart.Close();
        }
        #endregion
    }
}
